import mx.transitions.*;
import mx.transitions.easing.*;

class lib.modula.TxtResolver
{
	private var _content:String;
	private var display_tf:TextField;
	private var _path:MovieClip;

	private var blockArr:Array;
	private var currentBlockNum:Number=0;

	private var currentTextFormat:TextFormat;
	private var appendTextFormat:TextFormat;

	private var appendBlockFlag:Boolean=true;

	private var MLFDispatcher;

	private var filling_rect:MovieClip;
	private var fillingSpeed:Number=300;	// ms
	private var fillingTween:Tween;
	private var threshold:Number=0.8;

	public function TxtResolver(path:MovieClip, dispatcher)
	{
		trace("*TxtResolver constructor..."+path);
		_path=path;
		MLFDispatcher=dispatcher;
		MLFDispatcher.addEventListener("onTxtSync", this);
		createDisplayTextField();
		currentTextFormat=new TextFormat();
		currentTextFormat.color=0x0000ff;
		appendTextFormat=new TextFormat();
		appendTextFormat.color=0x666666;
		// _status=new Object();
	}

	public function close()
	{
		MLFDispatcher.removeEventListener("onTxtSync", this);
	}

	public function accessCurrentBlockNum():Number
	{
		return currentBlockNum;
	}

	/*public function accessCurrentBlockLength():Number
	{
		return blockArr[currentBlockNum].length;
	}*/

	private function onTxtSync(obj:Object)
	{
		switchBlock(obj.offset, obj.param);
	}

	public function get path():MovieClip
	{
		return _path;
	}

	public function set speed(fs:Number)
	{
		fillingSpeed=fs;
	}

	public function get speed():Number
	{
		return fillingSpeed;
	}

	public function set content(cont:String)
	{
		// for mode 0
		 _content=cont;
		/*// for mode 1
		_content="";
		var resArr=cont.split("\r\n");
		for (var i=0; i<resArr.length; i++)
		{
			if (resArr[i].charAt(0)==" ")
			{
				_content+="\r\n";
				// trace(_content.length);
			}
			_content+=resArr[i];
		}*/
		// append n-1 lines \r\n
		// var scrollNumPerPage=calcTotalPageScroll();
		// _content+="\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n";
	}

	public function get content():String
	{
		return _content;
	}

	private function createDisplayTextField()
	{
		display_tf=_path.createTextField("displayContent", _path.getNextHighestDepth(), 0, 0, _path._width, _path._height);
		// display_tf.selectable=false;
		display_tf.wordWrap=true;
	}

	private function refreshDisplayContent(blockNum:Number)
	{
		currentBlockNum=blockNum;
		display_tf.text=blockArr[blockNum].text;
		if (appendBlockFlag && blockNum<blockArr.length-1)
		{
			display_tf.text+=blockArr[blockNum+1].text;
			display_tf.setTextFormat(blockArr[blockNum].length, blockArr[blockNum+1].length+blockArr[blockNum].length, appendTextFormat);
		}
		display_tf.setTextFormat(0, blockArr[blockNum].length, currentTextFormat);
		display_tf.scroll=0;
	}

	public function changeDisplayFormat(formatObj:Object)
	{
		if (formatObj.currentTextFormat!=null)
		{
			for (var a in formatObj.currentTextFormat)
			{
				currentTextFormat[a]=formatObj.currentTextFormat[a];
			}
		}
		if (formatObj.appendTextFormat!=null)
		{
			for (var a in formatObj.appendTextFormat)
			{
				appendTextFormat[a]=formatObj.appendTextFormat[a];
			}
		}
		if (formatObj.appendBlockFlag!=null)
		{
			appendBlockFlag=formatObj.appendBlockFlag;
		}
		refreshDisplayContent(currentBlockNum);
	}

	public function scanBlocks(blockMin:Number, blockMax:Number)
	{
		blockArr=new Array();

		var preLength:Number=0;
		var midContent=_content;
		var cacheString="";
		var index=midContent.indexOf("\r\n");
		while (index>-1)
		{
			cacheString+=midContent.substr(0, index+4);
			midContent=midContent.substr(index+4);
			index=midContent.indexOf("\r\n");

			if (cacheString.length>=blockMin)
			{
				preLength=buildBlockItem(cacheString, preLength);
				cacheString="  ";
			}
		}
		buildBlockItem(cacheString+midContent, preLength);

		/*for (var i=0; i<blockArr.length; i++)
		{
			trace(i+": "+blockArr[i]);
		}*/
	}

	public function switchBlock(blockOffset:Number, blockNum:Number)
	{
		if (blockOffset==-1 && currentBlockNum>0)
		{
			refreshDisplayContent(currentBlockNum-1);
		}
		else if (blockOffset==1 && currentBlockNum<blockArr.length-1)
		{
			refreshDisplayContent(currentBlockNum+1);
		}
		else if (blockNum>-1 && blockNum<blockArr.length)
		{
			refreshDisplayContent(blockNum);
		}
	}

	private function buildBlockItem(content:String, preLength:Number):Number
	{
		var blockItem:Object=new Object();
		blockItem.text=content;
		blockItem.length=content.length;
		blockItem.start=preLength;
		preLength+=blockItem.length;
		blockArr.push(blockItem);

		return preLength;
	}

	public function initFillingBlock(width:Number, height:Number, x:Number, y:Number)
	{
		filling_rect.removeMovieClip();
		filling_rect=_path.createEmptyMovieClip("filling_rect", _path.getNextHighestDepth());
		filling_rect._x=x?x:0;
		filling_rect._y=y?y:0;
		var bg=filling_rect.createEmptyMovieClip("bg", filling_rect.getNextHighestDepth());
		// bg.lineStyle(-1, 0x000000);
		bg.moveTo(0, 0);
		// bg.beginFill(0x00ff00, 60);
		var colors=[0xf0f8fd, 0x00ff00];
		var alphas=[60, 60];
		var ratios=[0, 0xff];
		var matrix={matrixType:"box", x:100, y:0, w:300, h:16, r:(90/180)*Math.PI};
		bg.beginGradientFill("linear", colors, alphas, ratios, matrix);
		bg.lineTo(width, 0);
		bg.lineTo(width, height);
		bg.lineTo(0, height);
		bg.lineTo(0, 0);
		bg.endFill();

		var masker=bg.duplicateMovieClip("masker", filling_rect.getNextHighestDepth());
		bg.setMask(masker);
		var textLayer=filling_rect.createTextField("textLayer", filling_rect.getNextHighestDepth(), 0, 0, 100, 20);
		textLayer.textColor=0xff0000;
	}
	
	public function startFillingBlock()
	{
		// trace("filling_rect.masker: "+filling_rect.masker);
		// trace("start: "+-filling_rect.masker._width);
		// trace("end: "+filling_rect.masker._x);
		// trace("duration: "+Math.round(blockArr[currentBlockNum].length*speed/1000));
		filling_rect._visible=true;
		var gap=threshold;
		var totalLength=blockArr[currentBlockNum].length;
		var textLayer=filling_rect.textLayer;
		fillingTween=new Tween(filling_rect.masker, "_width", None.easeNone, 0, filling_rect.bg._width, Math.round(blockArr[currentBlockNum].length*speed/1000), true);
		fillingTween.onMotionChanged=function(target)
		{
			// trace("onMotionChanged..."+target._time);
			// trace(target.obj._x+" "+target.obj._width);
			var progress=Math.round(target._time/target._duration*totalLength);
			textLayer.text=progress+" / "+totalLength;
			if (progress/totalLength>gap)
			{
				textLayer.textColor=0x000000;
			}
			else textLayer.textColor=0xff0000;
		}
	}

	public function stopFillingBlock()
	{
		fillingTween.stop();
		filling_rect._visible=false;
	}

}